package com.yodawnla.katana.scene;

import javax.microedition.khronos.opengles.GL10;

import org.anddev.andengine.entity.Entity;
import org.anddev.andengine.entity.IEntity;
import org.anddev.andengine.entity.modifier.AlphaModifier;
import org.anddev.andengine.entity.modifier.IEntityModifier.IEntityModifierListener;
import org.anddev.andengine.entity.modifier.LoopEntityModifier;
import org.anddev.andengine.entity.modifier.MoveXModifier;
import org.anddev.andengine.entity.modifier.ScaleModifier;
import org.anddev.andengine.entity.modifier.SequenceEntityModifier;
import org.anddev.andengine.entity.scene.background.ColorBackground;
import org.anddev.andengine.entity.sprite.AnimatedSprite;
import org.anddev.andengine.entity.sprite.Sprite;
import org.anddev.andengine.util.modifier.IModifier;
import org.anddev.andengine.util.modifier.ease.EaseExponentialIn;
import org.anddev.andengine.util.modifier.ease.EaseQuintIn;

import android.view.KeyEvent;

import com.yodawnla.katana.Player;
import com.yodawnla.katana.R;
import com.yodawnla.katana.Hud.PushHud;
import com.yodawnla.katana.Hud.ResultHud;
import com.yodawnla.katana.Hud.SkillHud;
import com.yodawnla.katana.Hud.TalkHud;
import com.yodawnla.katana.Hud.TalkHud.ITalkHudListener;
import com.yodawnla.katana.system.Fonts;
import com.yodawnla.katana.system.ME;
import com.yodawnla.katana.system.SE;
import com.yodawnla.katana.system.Tex;
import com.yodawnla.lib.YoActivity;
import com.yodawnla.lib.YoScene;
import com.yodawnla.lib.network.YoBTScene;
import com.yodawnla.lib.util.YoMusicStateListener;
import com.yodawnla.lib.util.particle.YoEmitter;
import com.yodawnla.lib.util.tool.YoTimer;
import com.yodawnla.lib.util.tool.YoTimer.TimerEvent;
import com.yodawnla.lib.util.widget.YoButton;
import com.yodawnla.lib.util.widget.YoText;

public abstract class GameScene extends YoBTScene
{
	// protected YoText mInfoText;

	protected int mOpponentScore;

	protected YoTimer mTimer;
	protected YoTimer mWaitTimer;
	// protected YoTimer mEffectTimer;
	protected YoTimer mPullTimer; // 拔刀之後開始等對方的計時器
	protected YoTimer mStoryTimer;
	YoTimer mRecoverBladeTimer; // 收刀動畫用

	// protected int mMySp;
	// protected boolean mStart = false;
	// protected boolean mHasPull;
	// protected boolean mJudged = true;
	// protected boolean mStartTimer = false;

	protected AnimatedSprite mMeStand;
	// protected AnimatedSprite mMeStandDie;
	protected AnimatedSprite mMeAttack;
	protected AnimatedSprite mMeRecover;
	protected Sprite mMeSpeedEffect;

	protected AnimatedSprite mEnemyStand;
	// protected AnimatedSprite mEnemyStandDie;
	protected AnimatedSprite mEnemyAttack;
	protected AnimatedSprite mEnemyRecover;
	protected Sprite mEnemySpeedEffect;

	protected Sprite mBlood;

	protected Sprite mPrepare;
	protected Sprite mJudge;

	protected Sprite mGrass;
	protected Sprite mGrass2;

	protected Sprite mBanboo;
	protected Sprite mBanboo2;

	protected Sprite mRed;

	protected ColorBackground mColorBackground;

	// protected TickerText mStoryText;
	protected YoText mKillCountText;
	// protected YoButton mNextStageBtn;
	// YoText mLifeCountText;

	protected YoEmitter mLeafEffect;
	protected YoEmitter mBloodEffect1;
	// protected YoEmitter mBloodEffect2;
	// protected YoEmitter mBloodEffect3;
	protected YoEmitter mBloodEffect4;

	protected Entity mTransitEntity;

	public static final int ANIMATION_TIME = 350;

	protected String mEnemyName;
	protected String mEnemyGreetText;
	protected String mEnemyWinText;
	protected String mEnemyLoseText;
	protected String mEnemySkillText;
	protected String mEnemyTitleText;
	protected int mEnemyFaceType;

	protected Sprite mKniftEffect;
	protected boolean mIsPush = false;
	protected YoButton mTaiko1;
	protected YoButton mTaiko2;

	protected boolean mSingleMode = false;

	Sprite mWin1;
	Sprite mWin2;
	Sprite mLose1;
	Sprite mLose2;

	Player mPlayer = Player.getInstance();

	@Override
	public void onEnterScene()
	{
		setAdVisible(false);
		mStartJudge = false;
		stopMusic_FadeOut(1, new YoMusicStateListener()
		{
			public void onMusicFadeOutComplete()
			{
				playMusic_FadeIn(ME.BGM, 1);
			}

			public void onMusicFadeInComplete()
			{
			}
		});

		// TalkHud.getInstance();
		// SkillHud.getInstance();

		mColorBackground = new ColorBackground(1, 1, 1);
		mScene.setBackground(mColorBackground);

		mBanboo = new Sprite(0, 132, 800, 269, getTexture(Tex.Banboo));
		this.attachChild(mBanboo);

		mBanboo2 = new Sprite(800, 132, 800, 269, getTexture(Tex.Banboo));
		this.attachChild(mBanboo2);

		mRed = new Sprite(-100, -100, 1000, 1000, getTexture(Tex.White));
		mRed.setColor(1, 0, 0);
		mRed.setAlpha(0.8f);
		this.attachChild(mRed);
		mRed.setVisible(false);

		mKillCountText = new YoText(0, 15, Fonts.WHITE25, 10);
		mKillCountText.setColor(0, 0, 0);
		this.attachChild(mKillCountText);
		setKillCountText(mPlayer.getMaxKillTemp());

		mMeStand = new AnimatedSprite(26, 275, getTiledTexture(Tex.Tiled.WarriorStand)); // 184
																							// 275
		this.attachChild(mMeStand);
		mMeStand.animate(new long[] { ANIMATION_TIME, ANIMATION_TIME }, 0, 1, -1);

		// mMeStandDie = new AnimatedSprite(140, 313,
		// getTiledTexture(Tex.Tiled.WarriorAttack).deepCopy());
		// this.attachChild(mMeStandDie);
		// mMeStandDie.setVisible(false);

		mMeAttack = new AnimatedSprite(627, 313, getTiledTexture(Tex.Tiled.WarriorAttack));
		this.attachChild(mMeAttack);
		mMeAttack.setVisible(false);

		mMeSpeedEffect = new Sprite(490, 323, getTexture(Tex.SpeedEffect));
		this.attachChild(mMeSpeedEffect);
		mMeSpeedEffect.setVisible(false);

		mMeRecover = new AnimatedSprite(660, 275, getTiledTexture(Tex.Tiled.WarriorStand).deepCopy());
		this.attachChild(mMeRecover);
		mMeRecover.setCurrentTileIndex(2);
		mMeRecover.setVisible(false);

		mEnemyStand = new AnimatedSprite(627, 275, getTiledTexture(Tex.Tiled.WarriorStand).deepCopy()); // 533 275
		mEnemyStand.setFlippedHorizontal(true);
		this.attachChild(mEnemyStand);
		mEnemyStand.setVisible(false);
		mEnemyStand.animate(new long[] { ANIMATION_TIME, ANIMATION_TIME }, 0, 1, -1);

		mKniftEffect = new Sprite(10, 300, getTexture(Tex.knifeEffect));
		mKniftEffect.setVisible(false);
		mKniftEffect.setScale(0);
		this.attachChild(mKniftEffect);

		// mEnemyStandDie = new AnimatedSprite(510, 313,
		// getTiledTexture(Tex.Tiled.WarriorAttack).deepCopy());
		// mEnemyStandDie.setFlippedHorizontal(true);
		// this.attachChild(mEnemyStandDie);
		// mEnemyStandDie.setVisible(false);

		mEnemyAttack = new AnimatedSprite(26, 313, getTiledTexture(Tex.Tiled.WarriorAttack).deepCopy());
		mEnemyAttack.setFlippedHorizontal(true);
		this.attachChild(mEnemyAttack);
		mEnemyAttack.setVisible(false);

		mEnemySpeedEffect = new Sprite(39, 323, getTexture(Tex.SpeedEffect).deepCopy());
		mEnemySpeedEffect.setFlippedHorizontal(true);
		this.attachChild(mEnemySpeedEffect);
		mEnemySpeedEffect.setVisible(false);
		mEnemySpeedEffect.setFlippedVertical(true);

		mEnemyRecover = new AnimatedSprite(50, 275, getTiledTexture(Tex.Tiled.WarriorStand).deepCopy());
		mEnemyRecover.setFlippedHorizontal(true);
		this.attachChild(mEnemyRecover);
		mEnemyRecover.setCurrentTileIndex(2);
		mEnemyRecover.setVisible(false);

		mGrass = new Sprite(0, 347, 800, 133, getTexture(Tex.Grass));
		this.attachChild(mGrass);

		mGrass2 = new Sprite(800, 347, 800, 133, getTexture(Tex.Grass));
		this.attachChild(mGrass2);

		mTaiko1 = new YoButton(this, 180, 384, getTexture(Tex.taiko))
		{
			@Override
			public void onPressedEvent()
			{
				playSound(SE.Taiko2);
				float offset = 0.3f;
				float scaleX = 1.2f;
				float scaleY = 1.2f;
				clearEntityModifiers();
				registerEntityModifier(new SequenceEntityModifier(new ScaleModifier(0.05f, scaleX, scaleX + offset, scaleY, scaleY - offset),
						new ScaleModifier(0.08f, scaleX + offset, scaleX, scaleY - offset, scaleY)));
			}
		};
		this.attachChild(mTaiko1);

		mTaiko2 = new YoButton(this, 528, 384, getTexture(Tex.taiko))
		{
			@Override
			public void onPressedEvent()
			{
				playSound(SE.Taiko1);
				float offset = 0.3f;
				float scaleX = 1.2f;
				float scaleY = 1.2f;
				clearEntityModifiers();
				registerEntityModifier(new SequenceEntityModifier(new ScaleModifier(0.05f, scaleX, scaleX + offset, scaleY, scaleY - offset),
						new ScaleModifier(0.08f, scaleX + offset, scaleX, scaleY - offset, scaleY)));
			}
		};
		this.attachChild(mTaiko2);
		mTaiko1.setVisible(false);
		mTaiko2.setVisible(false);

		mBlood = new Sprite(197, 56, 428, 295, getTexture(Tex.Blood1));
		this.attachChild(mBlood);
		mBlood.setVisible(false);

		mPrepare = new Sprite(211, 67, getTexture(Tex.Prepare));
		this.attachChild(mPrepare);
		mPrepare.setAlpha(0);

		mJudge = new Sprite(228, 148, getTexture(Tex.Judge));
		this.attachChild(mJudge);
		mJudge.setVisible(false);

		// mInfoText = new YoText(200, 400, Fonts.WHITE20, "", 60);
		// this.attachChild(mInfoText);

		mTransitEntity = new Entity(-2000, 0);
		this.attachChild(mTransitEntity);

		Sprite t1 = new Sprite(0, 0, 184, 480, getTexture(Tex.Transit).deepCopy());
		mTransitEntity.attachChild(t1);

		Sprite black = new Sprite(t1.getWidth() - 20, -20, 1200, 600, getTexture(Tex.Black));
		mTransitEntity.attachChild(black);

		Sprite t2 = new Sprite(black.getX() + black.getWidth() - 20, 0, 184, 480, getTexture(Tex.Transit).deepCopy());
		t2.setFlippedHorizontal(true);
		mTransitEntity.attachChild(t2);

		// Sprite life = new Sprite(20, 420, getTexture(Tex.Life));
		// this.attachChild(life);
		//
		// mLifeCountText = new YoText(65, 440, Fonts.WHITE25, "x9");
		// this.attachChild(mLifeCountText);

		// mEngine.registerUpdateHandler(this);

		YoEmitter.Param param = new YoEmitter.Param(getTexture(Tex.Leaf), 1, 2, 3);
		param.velocityInit(0, 0, 80, 120);
		param.accelerationIniti(-60, 0);// -150, 60);
		param.rotationInit(0, 360);

		param.mX = 800;
		param.mY = -60;
		param.scaleInit(0.5f, 1f);
		param.mType = YoEmitter.EmitterType.RECTANGLE;
		param.mWidth = 800;
		param.mHeight = 24;
		param.mMinLifeTime = 6f;
		param.mMaxLifeTime = 10f;

		param.mSourceBlendFunction = GL10.GL_SRC_ALPHA;
		param.mDestinationBlendFunction = GL10.GL_ONE_MINUS_SRC_ALPHA;

		mLeafEffect = new YoEmitter(param);
		mLeafEffect.attachTo(mScene, this);
		mLeafEffect.pause();

		param = new YoEmitter.Param(getTexture(Tex.BloodEffect), 150, 200, 300);
		param.velocityInit(200, 300, -400, -150);
		param.accelerationIniti(0, 500);
		param.alphaInit(0.7f, 1);
		param.mX = 45;
		param.mY = 300;
		param.scaleInit(0.2f, 0.4f);
		param.rotationInit(0, 360);
		param.mType = YoEmitter.EmitterType.POINT;
		param.mMinLifeTime = 0.2f;
		param.mMaxLifeTime = 0.6f;

		param.mSourceBlendFunction = GL10.GL_SRC_ALPHA;
		param.mDestinationBlendFunction = GL10.GL_ONE_MINUS_SRC_ALPHA;

		mBloodEffect1 = new YoEmitter(param);

		mBloodEffect1.attachTo(mScene, this);
		mBloodEffect1.addAlphaModifier(1, 0, 0.1f, 0.6f);

		param = new YoEmitter.Param(getTexture(Tex.BloodEffect), 150, 200, 300);
		param.velocityInit(-200, -300, -400, -150);
		param.accelerationIniti(0, 500);
		param.alphaInit(0.7f, 1);
		param.mX = 700;
		param.mY = 300;
		param.scaleInit(0.2f, 0.4f);
		param.rotationInit(0, 360);
		param.mType = YoEmitter.EmitterType.POINT;
		param.mMinLifeTime = 0.2f;
		param.mMaxLifeTime = 0.6f;

		param.mSourceBlendFunction = GL10.GL_SRC_ALPHA;
		param.mDestinationBlendFunction = GL10.GL_ONE_MINUS_SRC_ALPHA;

		mBloodEffect4 = new YoEmitter(param);

		mBloodEffect4.attachTo(mScene, this);
		mBloodEffect4.addAlphaModifier(1, 0, 0.1f, 0.6f);

		mBloodEffect1.pause();
		mBloodEffect4.pause();

		mWin1 = new Sprite(227, 113, getTexture(Tex.Win1));
		mWin2 = new Sprite(430, 113, getTexture(Tex.Win2));

		mLose1 = new Sprite(227, 113, getTexture(Tex.Lose1));
		mLose2 = new Sprite(430, 113, getTexture(Tex.Lose2));

		this.attachChild(mWin1);
		this.attachChild(mWin2);

		this.attachChild(mLose1);
		this.attachChild(mLose2);

		mWin1.setVisible(false);
		mWin2.setVisible(false);
		mLose1.setVisible(false);
		mLose2.setVisible(false);
	}

	public void startMatch(final float time)
	{
//		Log.e(mTAG, "[startMatch] , time = " + time);
		mStartJudge = false;
		mLockEnemyScore = false;
		mOpponentScore = 0;
		mEnemyStand.setVisible(true);
		mEnemyStand.setPosition(800, mEnemyStand.getY());
		mEnemyStand.clearEntityModifiers();
		mEnemyStand.registerEntityModifier(new MoveXModifier(1.5f, 800, 697, new IEntityModifierListener() // 533
		{
			public void onModifierStarted(IModifier<IEntity> pModifier, IEntity pItem)
			{
			}

			public void onModifierFinished(IModifier<IEntity> pModifier, IEntity pItem)
			{
				// Log.e(mTAG, "[startMatch] enemy move to pos");
				mEnemyStand.stopAnimation(0);

				displayGreeting();
				stopMusic_FadeOut(7f);

				mStoryTimer = new YoTimer(8f) // 等待幾秒讓玩家看一下故事劇情才開始遊戲8
				{
					public void onTimePassed()
					{
						setWaitTime(time);
						this.stop();
					}
				};
				mStoryTimer.start();
			}
		}));

//		Log.e(mTAG, "[startMatch] stop move grass");
		setMoveGrass(false);
		mMeStand.stopAnimation(0);
	}

	public void setKillCountText(int killCount)
	{
		mKillCountText.setText(killCount + "人斬");
		mKillCountText.setPosition(800 - mKillCountText.getWidth() - 15, mKillCountText.getY());
	}

	public void setOpponentScore(int score)
	{
		if (!mLockEnemyScore)
			mOpponentScore = score;
	}

	public int getOpponentScore()
	{
		return mOpponentScore;
	}

	public void setWaitTime(float time)
	{
		// 全神貫注..
		playSound(SE.StartMatch);
		mEnemyStand.setVisible(true);

		mPrepare.setVisible(true);
		mPrepare.registerEntityModifier(new SequenceEntityModifier(new AlphaModifier(1f, 1, 1), new AlphaModifier(1f, 1, 0)));

		mTaiko1.setVisible(false);
		mTaiko2.setVisible(false);

		mWaitTimer = new YoTimer(time)
		{
			public void onTimePassed() // MEMO 時間到，開始拔刀判定
			{
				playSound(SE.Pull);
				mPrepare.setVisible(false);
				PushHud.getInstance().initPush();
				PushHud.getInstance().show();

				this.stop();
				mWaitTimer = null;
			}
		};
		mWaitTimer.start();
	}

	int mWinner;

	interface Winner
	{
		public final int NoOne = -1;
		public final int Me = 0;
		public final int Enemy = 1;
	}

	protected boolean mStartJudge = false;
	public void judge()
	{
		mStartJudge = true;
		mColorBackground.setColor(255, 0, 0);
		mRed.setVisible(true);

		createTempTimer(0.7f, new TimerEvent()
		{
			public void onTimePassed()
			{
				if (mTimer != null)
				{
					mTimer.stop();
					mTimer = null;
				}

				// mPlayer.setSp(mMySp);

				int myScore = Player.getInstance().getSpTemp();

				if (mOpponentScore < myScore) // 對方比我弱
				{
					// 贏了
					playerAttack(true);
					enemyAttack(true);
					mPlayer.addWinCount();
					mWinner = Winner.Me;
				}
				else if (myScore < mOpponentScore) // 我比對方弱
				{
					mWinner = Winner.Enemy;
					playerAttack(true);

					enemyAttack(true);
					mPlayer.addLoseCount();

				}
				else
				{
					// 平手
					mWinner = Winner.NoOne;
					playerAttack(true);
					enemyAttack(true);
				}

				// mPlayer.reduceEnergy();
				// mLifeCountText.setText("x"+mPlayer.getEnergy());
				setKillCountText(mPlayer.getMaxKillTemp());
			}
		}).start();
	}

//	public void winDirectly()
//	{
//		// mJudged = true;
//		// mInfoText.setText("不戰而勝!");
//
//		// setStoryText(
//		// "突然"+mEnemyTitleText+mEnemyName+"轉身逃跑\n\n"+
//		// "\t"+mPlayer.getName()+"「"+mPlayer.getWinText()+"」\n" +
//		// "這場決鬥的勝利者是"+mPlayer.getTitleString()+mPlayer.getName());
//
//		mPlayer.addWinCount();
//
//		if (mWaitTimer != null)
//		{
//			mWaitTimer.stop();
//			mWaitTimer = null;
//		}
//
//		if (mPullTimer != null)
//		{
//			mPullTimer.stop();
//			mPullTimer = null;
//		}
//
//		// _finishMatch(true);
//	}

	boolean mIWin;

	private void _finishMatch(final boolean win)
	{
		mIWin = win;
		mBlood.setVisible(true);
		mJudge.setVisible(true);

		mBlood.registerEntityModifier(new SequenceEntityModifier(new AlphaModifier(1, 1, 1), new AlphaModifier(1, 1, 0)));
		mJudge.registerEntityModifier(new SequenceEntityModifier(new AlphaModifier(1, 1, 1), new AlphaModifier(1, 1, 0, new IEntityModifierListener()
		{
			public void onModifierStarted(IModifier<IEntity> pModifier, IEntity pItem)
			{
			}

			public void onModifierFinished(IModifier<IEntity> pModifier, IEntity pItem)
			{
				if (win)
				{
					mWin1.setVisible(true);
					mWin1.setAlpha(1);
					mWin1.registerEntityModifier(new ScaleModifier(0.5f, 4, 1, new IEntityModifierListener()
					{
						public void onModifierStarted(IModifier<IEntity> pModifier, IEntity pItem)
						{
						}

						public void onModifierFinished(IModifier<IEntity> pModifier, IEntity pItem)
						{
							playSound(SE.Taiko1);

							mWin2.setVisible(true);
							mWin2.setAlpha(1);

							mWin2.registerEntityModifier(new ScaleModifier(0.5f, 4, 1, new IEntityModifierListener()
							{
								public void onModifierStarted(IModifier<IEntity> pModifier, IEntity pItem)
								{
								}

								public void onModifierFinished(IModifier<IEntity> pModifier, IEntity pItem)
								{
									playSound(SE.Taiko1);
									mWin1.registerEntityModifier(new SequenceEntityModifier(new AlphaModifier(1f, 1, 1),
											new AlphaModifier(0.5f, 1, 0)));
									mWin2.registerEntityModifier(new SequenceEntityModifier(new AlphaModifier(1f, 1, 1), new AlphaModifier(0.5f, 1,
											0, new IEntityModifierListener()
											{
												public void onModifierStarted(IModifier<IEntity> pModifier, IEntity pItem)
												{
												}

												public void onModifierFinished(IModifier<IEntity> pModifier, IEntity pItem)
												{
													ResultHud.getInstance().show(true);
												}
											})));
								}
							}, EaseQuintIn.getInstance()));
						}
					}, EaseQuintIn.getInstance()));
				} // win
				else
				// lose
				{
					mLose1.setVisible(true);
					mLose1.setAlpha(1);
					mLose1.registerEntityModifier(new ScaleModifier(0.5f, 4, 1, new IEntityModifierListener()
					{
						public void onModifierStarted(IModifier<IEntity> pModifier, IEntity pItem)
						{
						}

						public void onModifierFinished(IModifier<IEntity> pModifier, IEntity pItem)
						{
							playSound(SE.Taiko1);

							mLose2.setVisible(true);
							mLose2.setAlpha(1);

							mLose2.registerEntityModifier(new ScaleModifier(0.5f, 4, 1, new IEntityModifierListener()
							{
								public void onModifierStarted(IModifier<IEntity> pModifier, IEntity pItem)
								{
								}

								public void onModifierFinished(IModifier<IEntity> pModifier, IEntity pItem)
								{
									playSound(SE.Taiko1);
									mLose1.registerEntityModifier(new SequenceEntityModifier(new AlphaModifier(1f, 1, 1), new AlphaModifier(0.5f, 1,
											0)));
									mLose2.registerEntityModifier(new SequenceEntityModifier(new AlphaModifier(1f, 1, 1), new AlphaModifier(0.5f, 1,
											0, new IEntityModifierListener()
											{
												public void onModifierStarted(IModifier<IEntity> pModifier, IEntity pItem)
												{
												}

												public void onModifierFinished(IModifier<IEntity> pModifier, IEntity pItem)
												{
													ResultHud.getInstance().show(false);
												}
											})));
								}
							}, EaseQuintIn.getInstance()));
						}
					}, EaseQuintIn.getInstance()));
				}
				// onFinishMatch();
			}
		})));
	}

	/**
	 * 一場對戰結束
	 */
	abstract public void onFinishMatch();

	public void setMoveGrass(boolean move)
	{
		if (move)
		{
			float moveTime = 20;
			mGrass.clearEntityModifiers();
			mGrass.registerEntityModifier(new LoopEntityModifier(new MoveXModifier(moveTime, 0, -790)));

			mGrass2.clearEntityModifiers();
			mGrass2.registerEntityModifier(new LoopEntityModifier(new MoveXModifier(moveTime, 790, 0)));

			mBanboo.clearEntityModifiers();
			mBanboo.registerEntityModifier(new LoopEntityModifier(new MoveXModifier(moveTime, 0, -790)));

			mBanboo2.clearEntityModifiers();
			mBanboo2.registerEntityModifier(new LoopEntityModifier(new MoveXModifier(moveTime, 790, 0)));

		}
		else
		{
			mGrass.clearEntityModifiers();
			mGrass2.clearEntityModifiers();

			mBanboo.clearEntityModifiers();
			mBanboo2.clearEntityModifiers();
		}
	}

	public void setEnemyInfo(String name, String greet, String winString, String loseString, String skillString)
	{
		this.mEnemyName = name;
		this.mEnemyGreetText = greet;
		this.mEnemyWinText = winString;
		this.mEnemyLoseText = loseString;
		this.mEnemySkillText = skillString;
	}

	public void setEnemyFace(int faceID)
	{
		this.mEnemyFaceType = faceID;
	}

	public int getEnemyFaceType()
	{
		return mEnemyFaceType;
	}

	public void setEnemyTitle(int titleID)
	{
		switch (titleID)
		{
		case 0:// 路人
			mEnemyTitleText = YoActivity.getBaseActivity().getRString(R.string.title0);
			break;
		case 1:// 見習侍
			mEnemyTitleText = YoActivity.getBaseActivity().getRString(R.string.title1);
			break;
		case 2:// 浪人
			mEnemyTitleText = YoActivity.getBaseActivity().getRString(R.string.title2);
			break;
		case 3:// 達人
			mEnemyTitleText = YoActivity.getBaseActivity().getRString(R.string.title3);
			break;
		case 4:// 劍士
			mEnemyTitleText = YoActivity.getBaseActivity().getRString(R.string.title4);
			break;
		case 5:// 劍豪
			mEnemyTitleText = YoActivity.getBaseActivity().getRString(R.string.title5);
			break;
		case 6:// 劍聖
			mEnemyTitleText = YoActivity.getBaseActivity().getRString(R.string.title6);
			break;
		case 7:// 劍神
			mEnemyTitleText = YoActivity.getBaseActivity().getRString(R.string.title7);
			break;
		case 8:// 猛將
			mEnemyTitleText = YoActivity.getBaseActivity().getRString(R.string.title8);
			break;
		case 9:// 快刀侍
			mEnemyTitleText = YoActivity.getBaseActivity().getRString(R.string.title9);
			break;
		case 10:// 元大將軍
			mEnemyTitleText = YoActivity.getBaseActivity().getRString(R.string.title10);
			break;
		case 11:// 神速聖將
			mEnemyTitleText = YoActivity.getBaseActivity().getRString(R.string.title11);
			break;
		case 12:// 本國第一
			mEnemyTitleText = YoActivity.getBaseActivity().getRString(R.string.title12);
			break;
		case 13:// 天下第一
			mEnemyTitleText = YoActivity.getBaseActivity().getRString(R.string.title13);
			break;
		case 14:// 世界第一
			mEnemyTitleText = YoActivity.getBaseActivity().getRString(R.string.title14);
			break;
		case 15:// 宇宙第一
			mEnemyTitleText = YoActivity.getBaseActivity().getRString(R.string.title15);
			break;
		case 16:// 地獄鬼
			mEnemyTitleText = YoActivity.getBaseActivity().getRString(R.string.title16);
			break;
		case 17:// 一刀必殺
			mEnemyTitleText = YoActivity.getBaseActivity().getRString(R.string.title17);
			break;
		case 18:// 萬夫莫敵
			mEnemyTitleText = YoActivity.getBaseActivity().getRString(R.string.title18);
			break;
		case 19:// 黃金羅漢
			mEnemyTitleText = YoActivity.getBaseActivity().getRString(R.string.title19);
			break;
		case 20:// 拔刀齋
			mEnemyTitleText = YoActivity.getBaseActivity().getRString(R.string.title20);
			break;
		case 21:// 百人斬
			mEnemyTitleText = YoActivity.getBaseActivity().getRString(R.string.title21);
			break;
		case 22:// 千人斬
			mEnemyTitleText = YoActivity.getBaseActivity().getRString(R.string.title22);
			break;
		case 23:// 被人斬
			mEnemyTitleText = YoActivity.getBaseActivity().getRString(R.string.title23);
			break;
		case 24:// 六天魔王
			mEnemyTitleText = YoActivity.getBaseActivity().getRString(R.string.title24);
			break;
		case 25:// 嗜神者
			mEnemyTitleText = YoActivity.getBaseActivity().getRString(R.string.title25);
			break;
		case 26:// 戰國最強
			mEnemyTitleText = YoActivity.getBaseActivity().getRString(R.string.title26);
			break;
		case 27:// 傳說之侍
			mEnemyTitleText = YoActivity.getBaseActivity().getRString(R.string.title27);
			break;
		}
	}

	public void displayGreeting()
	{
		SkillHud.getInstance().initTalk(mEnemyName, mEnemySkillText, mEnemyFaceType);
		ResultHud.getInstance().initTalk(mEnemyName, mEnemyTitleText, mEnemyWinText, mEnemyLoseText, mEnemyFaceType);
		TalkHud.getInstance().initTalk(mEnemyName, mEnemyTitleText, mEnemyFaceType, new ITalkHudListener()
		{
			public void onHudInitFinish()
			{

				TalkHud.getInstance().showTalk(true, mPlayer.getGreetText());
				createTempTimer(2, new TimerEvent()
				{
					public void onTimePassed()
					{
						TalkHud.getInstance().showTalk(false, mEnemyGreetText);
						createTempTimer(5, new TimerEvent()
						{
							public void onTimePassed()
							{
								TalkHud.getInstance().hide();
								stop();
							}
						}).start();
						stop();
					}
				}).start();

			}
		});

	}

	// protected void setStoryText(final String text)
	// {
	// mBaseActivity.runOnUpdateThread(new Runnable()
	// {
	// public void run()
	// {
	// if (mStoryText != null)
	// {
	// mStoryText.reset();
	// mStoryText.detachChildren();
	// mStoryText.setPosition(-10000, -10000);
	// mStoryText.setVisible(false);
	// mStoryText.clearEntityModifiers();
	// mStoryText.clearUpdateHandlers();
	// mStoryText.detachSelf();
	// }
	//
	// mStoryText = new TickerText(20, 20, getFont(Fonts.WHITE25), text,
	// HorizontalAlign.LEFT, 15);//new YoText(20, 20, Fonts.SuFaW25, 300);
	// mStoryText.setColor(0, 0, 0);
	// attachChild(mStoryText);
	// }
	// });
	// }

	protected void resetScene()
	{
		mBloodEffect1.pause();
		// mBloodEffect2.pause();
		// mBloodEffect3.pause();
		mBloodEffect4.pause();

		mRed.setVisible(false);
		playMusic_FadeIn(ME.BGM, 1);
		// setStoryText("");
		mTransitEntity.registerEntityModifier(new MoveXModifier(0.55f, 800, -2000));

		tempTimer1 = new YoTimer(0.31f)
		{
			public void onTimePassed()
			{
				_resetDisplay();
				this.stop();
			}
		};
		tempTimer1.start();
	}

	YoTimer tempTimer1;

	private void _resetDisplay()
	{
		playerAttack(false);

		mEnemyStand.setVisible(false);
		mEnemyAttack.setVisible(false);

		mMeRecover.setVisible(false);
		// mMeStandDie.setVisible(false);

		mEnemyRecover.setVisible(false);
		// mEnemyStandDie.setVisible(false);

		mMeAttack.setCurrentTileIndex(0);
		mEnemyAttack.setCurrentTileIndex(0);

		mMeStand.animate(new long[] { ANIMATION_TIME, ANIMATION_TIME }, 0, 1, -1);
		mEnemyStand.animate(new long[] { ANIMATION_TIME, ANIMATION_TIME }, 0, 1, -1);
		setMoveGrass(true);

		mColorBackground.setColor(255, 255, 255);

		mPrepare.setVisible(false);
		mBlood.setVisible(false);
		mJudge.setVisible(false);
	}

	protected void playerAttack(boolean attack)
	{
		this.mMeStand.setVisible(!attack);
		this.mMeAttack.setVisible(attack);

		if (attack)
		{
			mMeAttack.registerEntityModifier(new MoveXModifier(1f, 26, 240, new IEntityModifierListener() // 140 240
					{
						public void onModifierStarted(IModifier<IEntity> pModifier, IEntity pItem)
						{
						}

						public void onModifierFinished(IModifier<IEntity> pModifier, IEntity pItem)
						{
							mMeAttack.setPosition(627, 313);
							mMeSpeedEffect.setVisible(true);
							mMeSpeedEffect.registerEntityModifier(new ScaleModifier(0.8f, 1.5f, 0, 1, 1, EaseExponentialIn.getInstance()));
							mMeSpeedEffect.registerEntityModifier(new AlphaModifier(0.8f, 1f, 0.3f));// ,
																										// EaseExponentialIn.getInstance()));
							mMeSpeedEffect.setScaleCenterX(mMeSpeedEffect.getWidth() - 40);

							mKniftEffect.setVisible(true);
							mKniftEffect.clearEntityModifiers();
							mKniftEffect.registerEntityModifier(new SequenceEntityModifier(new ScaleModifier(0.1f, 1, 1, 0, 1), new ScaleModifier(
									0.1f, 1, 1, 1, 0)));

							// playSound(SE.Finish);
							playSound(SE.Blood);

							switch (mWinner)
							{
							case Winner.Me:
								_finishMatch(true);
								mBloodEffect1.setEmitOnce(1, false);

								mRecoverBladeTimer = new YoTimer(2)
								{
									public void onTimePassed()
									{
										// TODO
										mEnemyAttack.animate(new long[] { ANIMATION_TIME * 2, ANIMATION_TIME }, new int[] { 0, 2 }, 0, null);

										mMeAttack.setVisible(false);
										mMeRecover.setVisible(true);
										mMeRecover.animate(new long[] { ANIMATION_TIME * 2, ANIMATION_TIME }, new int[] { 2, 0 }, 0, null);
										stop();
									}
								};
								mRecoverBladeTimer.start();
								break;

							case Winner.NoOne:
							case Winner.Enemy:
								_finishMatch(false);
								mBloodEffect4.setEmitOnce(1, false);

								mRecoverBladeTimer = new YoTimer(2)
								{
									public void onTimePassed()
									{
										// TODO
										mMeAttack.animate(new long[] { ANIMATION_TIME * 2, ANIMATION_TIME }, new int[] { 0, 2 }, 0, null);

										mEnemyAttack.setVisible(false);
										mEnemyRecover.setVisible(true);
										mEnemyRecover.animate(new long[] { ANIMATION_TIME * 2, ANIMATION_TIME }, new int[] { 2, 0 }, 0, null);
										stop();
									}
								};
								mRecoverBladeTimer.start();
								break;

							// case Winner.NoOne:
							// _finishMatch(true);
							// mBloodEffect1.setEmitOnce(1, false);
							// mBloodEffect4.setEmitOnce(1, false);
							//
							// mRecoverBladeTimer = new YoTimer(2)
							// {
							// public void onTimePassed()
							// {
							// mEnemyAttack.animate(
							// new long[]{ANIMATION_TIME*2, ANIMATION_TIME},
							// new int[]{0, 2}, 0, null);
							//
							// mMeAttack.animate(
							// new long[]{ANIMATION_TIME*2, ANIMATION_TIME},
							// new int[]{0, 2}, 0, null);
							// stop();
							// }
							// };
							// mRecoverBladeTimer.start();
							// break;
							}
						}
					}, EaseQuintIn.getInstance()));
		}
		else
		{
			this.mMeSpeedEffect.setVisible(attack);
		}
	}

	protected void enemyAttack(boolean attack)
	{
		this.mEnemyStand.setVisible(!attack);
		this.mEnemyAttack.setVisible(attack);

		if (attack)
		{
			mEnemyAttack.registerEntityModifier(new MoveXModifier(1f, 697, 410, new IEntityModifierListener() // 510 410
					{
						public void onModifierStarted(IModifier<IEntity> pModifier, IEntity pItem)
						{
						}

						public void onModifierFinished(IModifier<IEntity> pModifier, IEntity pItem)
						{
							mEnemyAttack.setPosition(26, 313);
							mEnemySpeedEffect.setVisible(true);
							mEnemySpeedEffect.registerEntityModifier(new ScaleModifier(0.8f, 1.5f, 0, 1, 1, EaseExponentialIn.getInstance()));
							mEnemySpeedEffect.registerEntityModifier(new AlphaModifier(0.8f, 1f, 0.3f));
							mEnemySpeedEffect.setScaleCenterX(40);
						}
					}, EaseQuintIn.getInstance()));

			// mEnemySpeedEffect.registerEntityModifier(new ScaleModifier(0.8f,
			// 1.5f, 0, 1, 1, EaseExponentialIn.getInstance()));
			// mEnemySpeedEffect.registerEntityModifier(new AlphaModifier(0.8f,
			// 1f, 0.3f));//, EaseExponentialIn.getInstance()));
			// mEnemySpeedEffect.setScaleCenterX(40);
		}
		else
			mEnemySpeedEffect.setVisible(false);
	}

	@Override
	public void onExitScene()
	{
		// mLeafEffect.pause();
		//
		// mBloodEffect1.pause();
		// mBloodEffect2.pause();
		// mBloodEffect3.pause();
		// mBloodEffect4.pause();

		mLeafEffect.remove();
		mBloodEffect1.remove();
		// mBloodEffect2.remove();
		// mBloodEffect3.remove();
		mBloodEffect4.remove();
		// mStartTimer = false;

		// mEngine.unregisterUpdateHandler(this);

		// mBaseActivity.runOnUpdateThread(new Runnable()
		// {
		// public void run()
		// {
		// if (mStoryText != null)
		// {
		// mStoryText.reset();
		// mStoryText.detachChildren();
		// mStoryText.setPosition(-10000, -10000);
		// mStoryText.setVisible(false);
		// mStoryText.clearEntityModifiers();
		// mStoryText.clearUpdateHandlers();
		// mStoryText.detachSelf();
		// mStoryText = null;
		// }
		// }
		// });

		_resetDisplay();

		if (mTimer != null)
		{
			mTimer.stop();
			mTimer = null;
		}

		if (mWaitTimer != null)
		{
			mWaitTimer.stop();
			mWaitTimer = null;
		}

		if (mPullTimer != null)
		{
			mPullTimer.stop();
			mPullTimer = null;
		}

		/*
		 * if(mEffectTimer != null) { mEffectTimer.stop(); mEffectTimer = null; }
		 */

		if (mStoryTimer != null)
		{
			mStoryTimer.stop();
			mStoryTimer = null;
		}

		if (mRecoverBladeTimer != null)
		{
			mRecoverBladeTimer.stop();
			mRecoverBladeTimer = null;
		}

		if (tempTimer1 != null)
		{
			tempTimer1.stop();
			tempTimer1 = null;
		}

		this.cleanScene();
	}

	// public void updateEnergyText()
	// {
	// mLifeCountText.setText("x" + mPlayer.getEnergy());
	// }

	@Override
	public boolean onKeyDown(final int pKeyCode, final KeyEvent pEvent)
	{
		if (pKeyCode == KeyEvent.KEYCODE_BACK && pEvent.getAction() == KeyEvent.ACTION_DOWN)
		{
			playSound("SeClick");
			// toScene("TitleScene");
			return true;
		}
		return false;
	}

	public boolean isSingleMode()
	{
		return mSingleMode;
	}
	
	boolean mLockEnemyScore = false;
	public void lockEnemyScore(boolean lock)
	{
		mLockEnemyScore = lock;
	}

	public abstract void nextStage();

	public abstract void exitBattle();

	// public void onUpdate(final float pSecondsElapsed)
	// {
	// if (!mStartTimer) // 遊戲開始之後才會計時
	// return;
	//
	// mMyTime += pSecondsElapsed;
	// }
	//
	// public void reset()
	// {
	// mMyTime = 0;
	// }
}